package orders

import (
	"cloud_android_backend/api/common"
	"cloud_android_backend/pkg/middleware/authorization"
	model "cloud_android_backend/pkg/models/users"
	"cloud_android_backend/pkg/modules/orders"
	"cloud_android_backend/pkg/modules/payment"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/golang/glog"
	"github.com/smartwalle/alipay/v3"
	rb "modules.tenxcloud.com/common/middleware"
	"net/http"
	"strconv"
)

func Register(application *gin.RouterGroup) {

	//application.GET("/video/list", authorization.TokenCheck, GetVideoList)
	//application.POST("/video/upload", rb.RequestBody, authorization.TokenCheck, UploadVideo)
	application.POST("/order/create", rb.RequestBody, authorization.TokenCheck, CreateOrder)
	//application.POST("/app/update/:appId", rb.RequestBody, authorization.TokenCheck, UpdateApp)
	//application.POST("/app/delete/:appId", rb.RequestBody, authorization.TokenCheck, DeleteApp)
	//application.GET("/app/info/:appId", rb.RequestBody, authorization.TokenCheck, GetAppDetail)
	application.POST("/pay/wechat_callback", WechatPayCallBack)
	application.GET("/order/status", GetOrderStatus)
	application.GET("/order/list", authorization.TokenCheck, OrderLists)
	application.GET("/pay/alipay_return", AlipayReturn)
	application.POST("/pay/alipay_callback", AlipayNotify)
}

func CreateOrder(c *gin.Context) {
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	//print(current)
	body, _ := c.Get(rb.RequestBodyKey)
	orderForm := orders.CreateOrderReq{}
	if err := json.Unmarshal(body.([]byte), &orderForm); err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	orderForm.ClientIp = c.ClientIP()
	orderForm.DeviceInfo = c.Request.UserAgent()
	result, err := orders.CreateReChargeOrderAndPay(orderForm, current.UserID)
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	c.JSON(http.StatusOK, common.SuccessResponse(result))
}

func WechatPayCallBack(c *gin.Context) {
	err := payment.WechatCallbackHandler(c)
	if err != nil {
		glog.Error(err)
		c.JSON(http.StatusOK, gin.H{"code": "FAILED", "message": "失败"})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": "SUCCESS", "message": "成功"})
}

func GetOrderStatus(c *gin.Context) {
	OrderId := c.Query("orderId")
	TradeNo := c.Query("trade_no")
	var OrderIdInt int64
	var err error
	if OrderId != "" {
		OrderIdInt, err = strconv.ParseInt(OrderId, 10, 64)
		if err != nil {
			c.JSON(common.ErrorResponse(err.Error()))
			return
		}
	}

	order, err := orders.GetOrderStatus(OrderIdInt, TradeNo)
	if err != nil {
		c.JSON(common.ErrorResponse(err.Error()))
		return
	}
	c.JSON(http.StatusOK, common.SuccessResponse(order))
}

func OrderLists(c *gin.Context) {
	li, exists := c.Get(authorization.LoginUserKey)
	if !exists {
		c.AbortWithStatusJSON(common.ErrorResponse("get user from content failed"))
		return
	}
	current := li.(*model.User)
	page := c.Query("page")
	pageInt, err := strconv.Atoi(page)
	if err != nil {
		pageInt = 1
	}
	size := c.Query("size")
	sizeInt, err := strconv.Atoi(size)
	if err != nil {
		sizeInt = 15
	}
	searchMap := make(map[string]interface{})

	searchStatus := c.Query("status")
	if searchStatus != "" {
		searchStatusInt, _ := strconv.Atoi(searchStatus)
		searchMap["status"] = searchStatusInt
	}
	searchStartTime := c.Query("startTime")
	if searchStartTime != "" {
		searchMap["startTime"] = searchStartTime
	}
	searchEndTime := c.Query("endTime")
	if searchEndTime != "" {
		searchMap["endTime"] = searchEndTime
	}
	searchTransType := c.Query("transType")
	if searchTransType != "" {
		searchMap["transType"] = searchTransType
	}
	searchProject := c.Query("project")
	if searchProject != "" {
		searchProjectInt, _ := strconv.Atoi(searchProject)
		searchMap["orderType"] = searchProjectInt
	}
	offset := (pageInt - 1) * sizeInt
	orderList, total, err := orders.GetOrderList(current.UserID, offset, sizeInt, searchMap)
	c.JSON(http.StatusOK, common.SuccessPagination(orderList, sizeInt, pageInt, int64(total)))
}

func AlipayReturn(c *gin.Context) {
	req := c.Request
	err := req.ParseForm()
	if err != nil {
		c.String(http.StatusBadRequest, "参数解析错误")
		return
	}
	outTradeNo := req.Form.Get("out_trade_no")
	tradeNo := req.Form.Get("trade_no")
	tradeStatus := req.Form.Get("trade_status")
	fmt.Println("out_trade_no:", outTradeNo)
	fmt.Println("trade_no:", tradeNo)
	fmt.Println("trade_status:", tradeStatus)

	if err := payment.AlipayClient.VerifySign(req.Form); err != nil {
		tradeStatus = "VERIFY_SIGN_FAILED"
	}

	// 重定向到前端支付结果页面
	frontendURL := fmt.Sprintf(
		"https://%s/payment/result?out_trade_no=%s&trade_no=%s&status=%s",
		c.Request.Host,
		outTradeNo,
		tradeNo,
		tradeStatus,
	)

	c.Redirect(http.StatusFound, frontendURL)
}

func AlipayNotify(c *gin.Context) {
	err := payment.AlipayCallback(c)
	if err != nil {
		glog.Errorf("处理支付会掉失败：%v", err)
		c.String(http.StatusBadRequest, "支付回调失败")
		return
	}
	// 确认收到通知
	alipay.AckNotification(c.Writer)
}
